﻿using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace DoubanFM.ViewModel
{
    /// <summary>
    /// Channel group view model.
    /// </summary>
    public class ChannelGroupViewModel : ViewModelCommon
    {
        public ChannelGroupViewModel(string uniqueId, string title, string smallImagePath, string largeImagePath, string description)
            : base(uniqueId, title, smallImagePath, largeImagePath, description)
        {
            Items.CollectionChanged += ItemsCollectionChanged;
        }

        // TODO: Bind to setting
        private int _topItemsCount = 12;
        public int TopItemsCount
        {
            get { return _topItemsCount; }
            set { SetProperty(ref _topItemsCount, value); }
        }

        private void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            // Provides a subset of the full items collection to bind to from a GroupedChannelsPage
            // for two reasons: GridView will not virtualize large items collections, and it
            // improves the user experience when browsing through groups with large numbers of
            // items.
            //
            // Default: A maximum of 12 items are displayed because it results in filled grid columns
            // whether there are 1, 2, 3, 4, or 6 rows displayed

            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if (e.NewStartingIndex < _topItemsCount)
                    {
                        TopItems.Insert(e.NewStartingIndex, Items[e.NewStartingIndex]);
                        if (TopItems.Count > _topItemsCount)
                        {
                            TopItems.RemoveAt(_topItemsCount);
                        }
                    }
                    break;
                case NotifyCollectionChangedAction.Move:
                    if (e.OldStartingIndex < _topItemsCount && e.NewStartingIndex < _topItemsCount)
                    {
                        TopItems.Move(e.OldStartingIndex, e.NewStartingIndex);
                    }
                    else if (e.OldStartingIndex < _topItemsCount)
                    {
                        TopItems.RemoveAt(e.OldStartingIndex);
                        TopItems.Add(Items[_topItemsCount - 1]);
                    }
                    else if (e.NewStartingIndex < _topItemsCount)
                    {
                        TopItems.Insert(e.NewStartingIndex, Items[e.NewStartingIndex]);
                        TopItems.RemoveAt(_topItemsCount);
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    if (e.OldStartingIndex < _topItemsCount)
                    {
                        TopItems.RemoveAt(e.OldStartingIndex);
                        if (Items.Count >= _topItemsCount)
                        {
                            TopItems.Add(Items[_topItemsCount - 1]);
                        }
                    }
                    break;
                case NotifyCollectionChangedAction.Replace:
                    if (e.OldStartingIndex < _topItemsCount)
                    {
                        TopItems[e.OldStartingIndex] = Items[e.OldStartingIndex];
                    }
                    break;
                case NotifyCollectionChangedAction.Reset:
                    TopItems.Clear();
                    while (TopItems.Count < Items.Count && TopItems.Count < _topItemsCount)
                    {
                        TopItems.Add(Items[TopItems.Count]);
                    }
                    break;
            }
        }

        private readonly ObservableCollection<ChannelItemViewModel> _items = new ObservableCollection<ChannelItemViewModel>();
        public ObservableCollection<ChannelItemViewModel> Items
        {
            get { return _items; }
        }

        private readonly ObservableCollection<ChannelItemViewModel> _topItem = new ObservableCollection<ChannelItemViewModel>();
        public ObservableCollection<ChannelItemViewModel> TopItems
        {
            get { return _topItem; }
        }
    }
}
